package web.sms.core.shiro.chain;

import org.apache.shiro.web.filter.mgt.FilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import web.sms.core.pojo.UrlFilter;
import web.sms.mvc.service.bo.ShiroFilerChainManager;

import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Eoly on 2017/6/26.
 */
public class CustomPathMatchingFilterChainResolver extends PathMatchingFilterChainResolver {

    private CustomDefaultFilterChainManager customDefaultFilterChainManager;

    private final ShiroFilerChainManager shiroFilerChainManager;

    private final List<String> urlMapping;

    private final List<UrlFilter> urlFilters = new ArrayList<UrlFilter>();

    public CustomPathMatchingFilterChainResolver(ShiroFilerChainManager shiroFilerChainManager, List<String> urlMapping) {
        this.shiroFilerChainManager = shiroFilerChainManager;
        this.urlMapping = urlMapping;
        for (String configuration : urlMapping) {
            urlFilters.add(new UrlFilter(configuration));
        }
    }

    public void setCustomDefaultFilterChainManager(CustomDefaultFilterChainManager customDefaultFilterChainManager) {
        this.customDefaultFilterChainManager = customDefaultFilterChainManager;
        setFilterChainManager(customDefaultFilterChainManager);
    }

    public FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain) {


        // 每次url访问同步数据库设置
        // do 缓存处理同步数据
        shiroFilerChainManager.initFilterChains(urlFilters);

        FilterChainManager filterChainManager = getFilterChainManager();
        if (!filterChainManager.hasChains()) {
            return null;
        }

        String requestURI = getPathWithinApplication(request);

        List<String> chainNames = new ArrayList<String>();
        //the 'chain names' in this implementation are actually path patterns defined by the user.  We just use them
        //as the chain name for the FilterChainManager's requirements
        for (String pathPattern : filterChainManager.getChainNames()) {

            // If the path does match, then pass on to the subclass implementation for specific checks:
            if (pathMatches(pathPattern, requestURI)) {
                chainNames.add(pathPattern);
            }
        }

        if (chainNames.size() == 0) {
            return null;
        }

        return customDefaultFilterChainManager.proxy(originalChain, chainNames);
    }
}
